import gc, time, ntptime, network, socket, machine, asyncio
import st7789py as st
from machine import Pin, I2C, UART, PWM, SPI, Timer, WDT
from main import connect_wlan, ota
wdt = WDT(timeout=60000)
from esp32 import NVS
value = NVS(
    "Sensen"
)  # spacename是命名空间，也就是实例化的开辟了一个叫spacename的存储空间

jiaozhun = 0
# 创建串口对象
uart1 = UART(1, baudrate=9600, tx=4, rx=15)
uart2 = UART(2, baudrate=19200, tx=17, rx=16)
# 构造一个硬件SPI对象
spi = SPI(
    1,
    baudrate=30000000,
    polarity=0,
    phase=0,
    bits=8,
    firstbit=SPI.MSB,
    sck=Pin(13),
    mosi=Pin(12),
    miso=Pin(22),
)
# 创建显示屏对象
tft = st.ST7789(
    spi, 320, 240, reset=Pin(14), dc=Pin(27), cs=Pin(26), backlight=Pin(25), rotation=0
)


def tft7789():
#     tft.text(16, "00:00:00", 0, 0, st.color565(0, 0, 0), st.color565(255, 255, 255))
    tft.line(
        0, 16, 240, 16, st.color565(0, 0, 255)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.text(16, "xudianchi", 0, 17, st.color565(0, 0, 255), st.color565(255, 255, 255))
    tft.text(
        16,
        "U:00.00V   I:00.00A   P:000.0W",
        0,
        33,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        "U:00.00V   Q:100%     T:100C",
        0,
        49,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.line(
        3, 65, 60, 65, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(60, 65, 18, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        3, 83, 60, 83, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(3, 65, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.vline(3, 77, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.vline(0, 71, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        0, 71, 3, 71, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.line(
        0, 77, 3, 77, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.text(16, "0.00V", 12, 67, st.color565(0, 0, 0), st.color565(255, 255, 255))
    tft.line(
        64, 65, 120, 65, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(120, 65, 18, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        64, 83, 120, 83, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(64, 65, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.vline(64, 77, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        60, 71, 63, 71, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.line(
        60, 77, 63, 77, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.text(16, "0.00V", 72, 67, st.color565(0, 0, 0), st.color565(255, 255, 255))
    tft.line(
        124, 65, 180, 65, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(180, 65, 18, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        124, 83, 180, 83, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(124, 65, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.vline(124, 77, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        120, 71, 123, 71, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.line(
        120, 77, 123, 77, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.text(16, "0.00V", 132, 67, st.color565(0, 0, 0), st.color565(255, 255, 255))
    tft.line(
        184, 65, 240, 65, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(239, 65, 18, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        184, 83, 240, 83, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.vline(184, 65, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.vline(184, 77, 6, st.color565(0, 0, 0))  # 画一条竖线 1宽度，2高度，3长度
    tft.line(
        180, 71, 184, 71, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.line(
        180, 77, 184, 77, st.color565(0, 0, 0)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    tft.text(16, "0.00V", 192, 67, st.color565(0, 0, 0), st.color565(255, 255, 255))
    tft.line(
        0, 88, 240, 88, st.color565(0, 0, 255)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度

    tft.text(
        16, "taiyangneng", 0, 90, st.color565(0, 0, 255), st.color565(255, 255, 255)
    )
    tft.text(
        16,
        "U:00.00V   I:00.00A   P:000.0W",
        0,
        106,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        "U:00.00V   I:00.00A   T:000.0W",
        0,
        122,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    #     tft.text(16, "U:00.00V   I:00.00A   T:000.0W" , 0, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))
    tft.line(
        0, 154, 240, 154, st.color565(0, 0, 255)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度

    tft.text(16, "bingwang", 0, 155, st.color565(0, 0, 255), st.color565(255, 255, 255))
    tft.text(
        16,
        "I:     A   P:     W   Q:     %",
        0,
        171,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        "I:     A   P:     W   Q:     %",
        0,
        187,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.line(
        0, 204, 240, 204, st.color565(0, 0, 255)
    )  # 画一条横线 1起始位置，2高度，3结束位置，4高度
    BLK = PWM(Pin(25))
    BLK.freq(200)
    BLK.duty(500)


#     #第一行
#     tft.text(16, "88.88" , 16, 33,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 104, 33,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "888.8" , 192, 33,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第二行
#     tft.text(16, "88.88" , 16, 49,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "888" , 104, 49,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "888" , 192, 49,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第三行
#     tft.text(16, "8.88V" , 12, 67,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "8.88V" , 72, 67,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "8.88V" , 132, 67,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "8.88V" , 192, 67,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第四行
#     tft.text(16, "88.88" , 16, 106,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 104, 106,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 192, 106,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第五行
#     tft.text(16, "88.88" , 16, 122,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 104, 122,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 192, 122,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第六行
#     tft.text(16, "88.88" , 16, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 104, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 192, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第七行
#     tft.text(16, "88.88" , 16, 171,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 104, 171,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 192, 171,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     #第八行
#     tft.text(16, "88.88" , 16, 187,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 104, 187,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "88.88" , 192, 187,st.color565(0, 0, 0), st.color565(255, 255, 255))
def xdc_TFT():
    # 第一行
    tft.text(
        16, "%s" % (mppt[0]), 16, 33, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[0]), 104, 33, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[0]), 192, 33, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    # 第二行
    tft.text(
        16, "%s" % (mppt[7]), 16, 49, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[8]), 104, 49, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[10]), 192, 49, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    # 第三行
    tft.text(
        16, "%s" % (mppt[0]), 12, 67, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[0]), 72, 67, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[0]), 132, 67, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[0]), 192, 67, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )


def mppt_TFT():
    # 第四行
    tft.text(
        16, "%s" % (mppt[0]), 16, 106, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[1]), 104, 106, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[4]), 192, 106, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    # 第五行
    tft.text(
        16, "%s" % (mppt[2]), 16, 122, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[3]), 104, 122, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )
    tft.text(
        16, "%s" % (mppt[5]), 192, 122, st.color565(0, 0, 0), st.color565(255, 255, 255)
    )


#     #第六行
#     tft.text(16, "%s"%(), 16, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "%s"%(), 104, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))
#     tft.text(16, "%s"%(), 192, 138,st.color565(0, 0, 0), st.color565(255, 255, 255))


def ac_TFT():
    # 第七行
    tft.text(
        16,
        " %s" % (da[1] / 100),
        16,
        171,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        " %s " % int(da[2] / 100),
        104,
        171,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        " %s " %int(da[4]),
        192,
        171,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    # 第八行
    tft.text(
        16,
        " %s" % (ta[1] / 100),
        16,
        187,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        " %s " % int(ta[2] / 100),
        104,
        187,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )
    tft.text(
        16,
        " %s " %int(ta[4] ),
        192,
        187,
        st.color565(0, 0, 0),
        st.color565(255, 255, 255),
    )

# 巴法云
clientID = "4892bd7fe005ecbbccf35929157ec7e7"  # Client ID ，密钥，巴法云控制台获取
serverIP = "bemfa.com"  # 服务器地址
port = 8344  # 服务器端口
Error = None  # 记录报错
Exce = 3  # 报错次数

BFY_client = None  # 巴法云客户端
udp_client = None  #udp套接字客户端

# 艾掌控开关状态
k1 = 0
k2 = 0
k3 = 0
k4 = 0
k5 = 0
k6 = 0
k7 = 0
k8 = 0
t1 = 0
t3 = 0
t4 = 0
t5 = 0
f5 = 0
# 并网控制
OUT = PWM(Pin(5))  # 并网PWM 输出引脚
OUT.freq(10000)  # 并网PWM 输出频率
OUT.duty(0)  # 并网PWM 输出占空比
da = [0, 0, 0, 0, 0]  # 用电参数
ta = [0, 0, 0, 0, 0]  # 发电参数
A = 10  # 误差值
B = 0  # 并网电流递增值
C = 500  # 最大功率W
D = 20  # 最小功率W
i = 0  # 并网PWM
Ping_time = 0
time_ac = 2000
mppt = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
K_a = None  # 先记录初始值为 None
K_b = None  # 后记录初始值为 None

try:
    d = value.get_i32("d")
    d0 = value.get_i32("d0")  # 昨天发电
    d1 = value.get_i32("d1")  # 今天发电
    d2 = value.get_i32("d2")  # 当天用电
    d3 = value.get_i32("d3")  # 最大电流
    M1 = d1
    M2 = d2
except Exception as e:
    value.set_i32("d", 0)
    value.set_i32("d0", 0)
    value.set_i32("d1", 0)
    value.set_i32("d2", 0)
    value.set_i32("d3", 0)
    value.commit()  # 把存好的数据刷入实例化的命名空间，提交并保存。
    d = value.get_i32("d")
    d0 = value.get_i32("d0")  # 统计
    d1 = value.get_i32("d1")  # 昨天统计
    d2 = value.get_i32("d2")  # 当天统计
    d3 = value.get_i32("d3")  # 当天统计
    
    
async def AC():
    global A, B, C, D, i, t1, pwm, time_ac,f5
    while True:
        f5 += 1
        if da[2] / 100 < D or k1 != 1:
            if pwm == 0:
                i = 0
                OUT.duty(i)
            await CRC0()  # 用电功率
            await CRC1()  # 并网功率
            time_ac = 2
            await asyncio.sleep(2)

        else:
            await CRC0()  # 用电功率
            await CRC1()  # 并网功率
            Cha = int((da[2] / 100) - (ta[2] / 100))
    #         print(Cha    ,int(i)    ,da[2]    ,ta[2])
            if Cha > 50 and ta[2] / 100 < C:
                i += Cha*0.5
                print("+++++")
                       
            elif Cha > A+2 and ta[2] / 100 < C:
                i += 1
                print("+")    
                
            elif Cha < 0:
                i -= i * 0.5
                print("-----")
            elif Cha < A-2:
                i -= 1
                print("-")    

            i = max(0 , min( 1023 , i))    
            OUT.duty(int(i))
            pwm = 0
            time_ac = 0

async def CRC0():
    global da
    uart1.write(
        bytes([0x01, 0x03, 0x00, 0x48, 0x00, 0x08, 0xC4, 0x1A])
    )  # 发送该HEX数据
    await asyncio.sleep(0.1)
    shuju = uart1.read()
    if shuju != None:
        test_crc = 0xFFFF
        test_crc1 = 0x0000
        poly = 0xA001
        shuju1 = shuju[36:]
        numl = len(shuju1)
        for num in range(numl):
            test_crc1 = hex(shuju1[num])  #  test_crc1 接收到的效验码
        shuju = shuju[0:-2]
        numl = len(shuju)
        for num in range(numl):
            data = int(shuju[num])

            test_crc = (
                data & 0xFF
            ) ^ test_crc  # 把第一个8位二进制数据（既通讯信息帧的第一个字节）与16位的CRC寄存器的低8位相异或，把结果放于CRC寄存器，高八位数据不变；
            for bit in range(8):
                if (test_crc & 0x1) != 0:
                    test_crc >>= 1
                    test_crc ^= poly
                else:
                    test_crc >>= 1
        test_crc = hex(test_crc)[:4]  #   test_crc 计算到的效验码

        if test_crc == test_crc1:
            data = shuju.hex()
            da[0] = int(int((data[6:14]), 16) / 100)
            da[1] = int(int((data[14:22]), 16) / 100)
            da[2] = int(int((data[22:30]), 16) / 100)
            da[3] = int(int((data[30:38]), 16) / 100)
            da[4] = int(int((data[38:46]), 16) / 10)
    else:
        da = [0, 0, 0, 0, 0]


async def CRC1():
    global ta
    uart1.write(
        bytes([0x02, 0x03, 0x00, 0x48, 0x00, 0x08, 0xC4, 0x29])
    )  # 发送该HEX数据
    await asyncio.sleep(0.1)
    shuju = uart1.read()
    if shuju != None:
        test_crc = 0xFFFF
        test_crc1 = 0x0000
        poly = 0xA001
        shuju1 = shuju[36:]
        numl = len(shuju1)
        for num in range(numl):
            test_crc1 = hex(shuju1[num])  #  test_crc1 接收到的效验码
        shuju = shuju[0:-2]
        numl = len(shuju)
        for num in range(numl):
            data = int(shuju[num])
            test_crc = (
                data & 0xFF
            ) ^ test_crc  # 把第一个8位二进制数据（既通讯信息帧的第一个字节）与16位的CRC寄存器的低8位相异或，把结果放于CRC寄存器，高八位数据不变；
            for bit in range(8):
                if (test_crc & 0x1) != 0:
                    test_crc >>= 1
                    test_crc ^= poly
                else:
                    test_crc >>= 1
        test_crc = hex(test_crc)[:4]  #   test_crc 计算到的效验码
        if test_crc == test_crc1:
            data = shuju.hex()
            ta[0] = int(int((data[6:14]), 16) / 100)
            ta[1] = int(int((data[14:22]), 16) / 100)
            ta[2] = int(int((data[22:30]), 16) / 100)
            ta[3] = int(int((data[30:38]), 16) / 100)
            ta[4] = int(int((data[38:46]), 16) / 10)
            if ta[2] < 200:
                da[2] = da[2] + ta[2]
                ta[2] = 0

    else:
        ta = [0, 0, 0, 0, 0]


pwm = 0

def IM1253B():  # 上传并网数据
    AC1 = da[2]
    AC2 = ta[2]
    AC3 = da[1]
    AC4 = ta[1]
    AC5 = ta[0]
    AC1 = AC1.to_bytes(2, 0)
    AC1 = [ab for ab in AC1]
    AC2 = AC2.to_bytes(2, 0)
    AC2 = [ab for ab in AC2]
    AC3 = AC3.to_bytes(2, 0)
    AC3 = [ab for ab in AC3]
    AC4 = AC4.to_bytes(2, 0)
    AC4 = [ab for ab in AC4]
    AC5 = AC5.to_bytes(2, 0)
    AC5 = [ab for ab in AC5]
    ac = [0xFF, 0x08, 0x0B, 0x01]
    ac.extend(AC1)
    ac.extend(AC2)
    ac.extend(AC3)
    ac.extend(AC4)
    ac.extend(AC5)
    sum = 0
    for i in range(0, len(ac)):
        sum += ac[i]
    sum = sum & 0xFF
    ac.append(sum)
    #                 DC = [0XFF,0X08,0X07,0X00,0X31,0X39,0X00,0X99,0X03,0X15]
    #                 AC = [0XFF,0X08,0X07,0X01,0X31,0X39,0X00,0X99,0X03,0X15]
    #                 print(" DC发送的数据",DC)
    #                 print(" AC发送的数据",AC)

    uart2.write(bytes(ac))


def MPPT():  # 上传太阳能控制器数据
    global mppt, udp_client
    if not isinstance(udp_client,socket.socket):
        # 创建一个UDP套接字
        udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        # 非阻塞接收
        udp_client.setblocking(False)
        # 绑定本地的相关信息，如果不绑定，则系统会随机分配一个端口号
        local_addr = ("", 6060)
        # ip地址和端口号，ip一般不用写，表示本机的任何一个ip
        udp_client.bind(local_addr)
    try:
        # 尝试接收数据
        recv_data = udp_client.recvfrom(1024)
        # 解码接收到的数据
        recv_data = recv_data[0].decode()
        mppt[0] = float((recv_data.split(":"))[2])  # 蓄电池电压
        mppt[1] = float((recv_data.split(":"))[4])  # 蓄电池电流
        mppt[2] = float((recv_data.split(":"))[6])  # 光伏板电压
        mppt[3] = float((recv_data.split(":"))[8])  # 光伏板电流
        mppt[4] = float((recv_data.split(":"))[10])  # 光伏板功率
        mppt[5] = float((recv_data.split(":"))[12])  # 控制器温度
        mppt[6] = float((recv_data.split(":"))[14])  # 累计功率
        mppt[7] = float((recv_data.split(":"))[16])  # 蓝牙蓄电池电压
        mppt[8] = float((recv_data.split(":"))[18])  # 蓝牙蓄电池电流
        mppt[9] = float((recv_data.split(":"))[20])  # 蓝牙蓄电池电流
        mppt[10] = int((recv_data.split(":"))[22])  # 蓝牙蓄电池电量
        A = int(mppt[0] * 100).to_bytes(2, 0)
        A = [ab for ab in A]
        B = int(mppt[1] * 100).to_bytes(2, 0)
        B = [ab for ab in B]
        C = int(mppt[2] * 100).to_bytes(2, 0)
        C = [ab for ab in C]
        D = int(mppt[3] * 100).to_bytes(2, 0)
        D = [ab for ab in D]
        E = int(mppt[10]).to_bytes(2, 0)
        E = [ab for ab in E]
        M = [0xFF, 0x08, 0x0B, 0x02]
        M.extend(A)
        M.extend(B)
        M.extend(C)
        M.extend(D)
        M.extend(E)
        sum = 0
        for i in range(0, len(M)):
            sum += M[i]
        sum = sum & 0xFF
        M.append(sum)
        #                 print(M)
        uart2.write(bytes(M))
    except:
        pass


# 按键1外部中断函数
def key1_irq(key1):
    global val, t
    time.sleep_ms(1)  # 按键消抖
    if key1.value() == 0:
        val -= 1
        if val <= 0:
            val = 3
        print(val, "K1按键被按下")


# 按键2外部中断函数
def key2_irq(key2):
    global val
    time.sleep_ms(1)  # 按键消抖
    if key2.value() == 0:
        val += 1
        if val >= 4:
            val = 1
        print(val, "K2按键被按下")


def Bfyclient(self):
    global BFY_client, k1, k2, k3, k4, k5, k6, k7, k8, Ping_time, Exce, f5, Error, i, pwm
    try:
        if not connect_wlan() :
            tft.text(
                16, "Wifi", 200, 0, st.color565(0, 255, 255), st.color565(255, 255, 255)
            )
            BFY_client = None
            return
        elif not isinstance(BFY_client,socket.socket):
            print("巴法云")
            tft.text(16, "Wifi", 200, 0, st.color565(0, 0, 0), st.color565(255, 255, 255))
            addr_info = socket.getaddrinfo(serverIP, port)
            addr = addr_info[0][-1]
            BFY_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP的套接字,也可以不给定参数。默认为TCP通讯方式
            BFY_client.connect(addr)  # 设置要连接的服务器端的IP和端口,并连接
            BFY_client.send(("cmd=1&uid=" + clientID + "&topic=" "Auto" "\r\n").encode("utf-8"))
            BFY_client.setblocking(False)
            tft.text(32, "Bfy", 160, 0, st.color565(0, 255, 255), st.color565(255, 255, 255))
            if ota():
                with open('boot_count.txt', 'w') as f:
                    f.write(str(0))
                machine.reset()

        else :    
            Ping_time += 1
            if Ping_time >= 20:
                keeplive = f"cmd=2&uid={clientID}&topic=Auto/up&msg={"on"if i>0 else"off"}#{da[0]/100}#{da[2]/100}#{ta[2]/100}#{int(i)}#{int(d0/100)}#{int(d1/100)}#{int(d2/100)}#{int(d3/100)}#{k1}#{k2}#{k3}#{k4}#{k5}#{k6}#{k7}#{k8}#{f5}#{Error}\r\n"
                BFY_client.send(keeplive.encode("utf-8"))
                Ping_time = 0
                
            try:
                data = BFY_client.recv(256)  # 从服务器端套接字中读取1024字节数
                data = data.decode("utf-8")
                wdt.feed()#看门狗看门
                tft.text(32, "Bfy", 160, 0, st.color565(0, 0, 0), st.color565(255, 255, 255))
#                 print("心跳:",data)
                if len(data) > 60:
                    if data.find("K") > 0:
                        # print(data)
                        if data.find("K1_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x00, 0xFF, 0x0A]
                            uart2.write(bytes(M))
                            k1 = 1
                            print("k1打开")
                        elif data.find("K1_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x00, 0x00, 0x0B]
                            uart2.write(bytes(M))
                            k1 = 0
                            print("k1关闭")
                        elif data.find("K2_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x01, 0xFF, 0x0B]
                            uart2.write(bytes(M))
                            k2 = 1
                            print("k2打开")
                        elif data.find("K2_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x01, 0x00, 0x0C]
                            uart2.write(bytes(M))
                            k2 = 0
                            print("k2关闭")
                        elif data.find("K3_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x02, 0xFF, 0x0C]
                            uart2.write(bytes(M))
                            k3 = 1
                            print("k3打开")
                        elif data.find("K3_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x02, 0x00, 0x0D]
                            uart2.write(bytes(M))
                            k3 = 0
                            print("k3关闭")
                        elif data.find("K4_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x03, 0xFF, 0x0D]
                            uart2.write(bytes(M))
                            k4 = 1
                            print("k4打开")
                        elif data.find("K4_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x03, 0x00, 0x0E]
                            uart2.write(bytes(M))
                            k4 = 0
                            print("k4关闭")
                        elif data.find("K5_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x04, 0xFF, 0x0E]
                            uart2.write(bytes(M))
                            k5 = 1
                            print("k5打开")
                        elif data.find("K5_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x04, 0x00, 0x0F]
                            uart2.write(bytes(M))
                            k5 = 0
                            print("k5关闭")
                        elif data.find("K6_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x05, 0xFF, 0x0F]
                            uart2.write(bytes(M))
                            k6 = 1
                            print("k6打开")
                        elif data.find("K6_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x05, 0x00, 0x10]
                            uart2.write(bytes(M))
                            k6 = 0
                            print("k6关闭")
                        elif data.find("K7_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x06, 0xFF, 0x10]
                            uart2.write(bytes(M))
                            k7 = 1
                            print("k7打开")
                        elif data.find("K7_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x06, 0x00, 0x11]
                            uart2.write(bytes(M))
                            k7 = 0
                            print("k7关闭")
                        elif data.find("K8_on") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x07, 0xFF, 0x11]
                            uart2.write(bytes(M))
                            k8 = 1
                            print("k8打开")
                        elif data.find("K8_off") > 0:
                            M = [0xFF, 0x0A, 0x02, 0x07, 0x00, 0x12]
                            uart2.write(bytes(M))
                            k8 = 0
                            print("k8关闭")
                        t2 = 0

                    if data.find("update") > 0:
                        nvsshujubaocun()
                        with open('boot_count.txt', 'w') as f:
                            f.write(str(1))
                        print("升级")
                        machine.reset()

                    # if data.find('shezhi#canshu')>0:
                    #     keeplive = 'cmd=2&uid='+clientID+'&topic=Auto/up&msg=canshu#''%d''#''%d''#\r\n'%(Max,output)
                    #     client.send(keeplive.encode("utf-8"))
                    #     if data.find('Mxa:')>0:
                    #         z = data.find('Mxa:')+ 4
                    #         x = data.find('output:')
                    #         c = data.find('output:')+7
                    #         v = data.find('##')
                    #         if data[z:x] == '':
                    #             print(data[z:x])
                    #         else:
                    #             Max =int(data[z:x])
                    #         if data[c:v] == '':
                    #             print(data[c:v])
                    #         else:
                    #             output =int(data[c:v])
                    #         value.set_i32('Max',Max)
                    #         value.set_i32('output',output)
                    #         value.commit() # 把存好的数据刷入实例化的命名空间，提交并保存。
                    #     if data.find('Jiaozhui')>0:
                    #         output = Max
                    #         value.set_i32('Max',Max)
                    #         value.set_i32('output',int(output*1000000))
                    #         value.commit() # 把存好的数据刷入实例化的命名空间，提交并保存。
            except:
                pass
    except OSError as e:
        print("BFY:", e)
        client = None
        Error = e
        Exce += 1
        if Exce > 10:
            machine.reset()


def nvsshujubaocun():
    print("数据刷入实例化")
    value.set_i32("d", int(d))
    value.set_i32("d0", int(d0))
    value.set_i32("d1", int(d1))
    value.set_i32("d2", int(d2))
    value.set_i32("d3", int(d3))
    value.commit()  # 把存好的数据刷入实例化的命名空间，提交并保存。


# 定时器中断函数
def time_irq(self):
    global d, d0, d1, d2, d3, M1, M2, f5
    # 计算今天发电
    d1 += mppt[1] / 36

    # 计算用电电流
    d2 += (mppt[1] - mppt[8]) / 36

    # 计算最大发电电流
    if mppt[1] * 100 > d3:
        d3 = mppt[1] * 100

    if M1 != int(d1 / 100) or M2 != int(d2 / 100):
        M1 = int(d1 / 100)
        M2 = int(d2 / 100)
        nvsshujubaocun()
#     print("并网循环:", f5)
    f5 =0


async def shijian():
    global jiaozhun,d, d0, d1, d2, d3, f5
    print("时间")
    while True:
        await asyncio.sleep(1)
        t = time.localtime(time.time() + (8 * 3600))
        year = t[0]
        month = t[1]
        day = t[2]
        hour = t[3]
        minute = t[4]
        second = t[5]
        t1 = "{:0>2d}:{:0>2d}:{:0>2d}".format(hour, minute, second)
        t2 = "{:0>2d}:{:0>2d}:{:0>2d}".format(0, 0, 0)
        if t1 == t2:
            d0 = d1
            d1 = 0
            d2 = 0
            d3 = 0
        if jiaozhun != 1 and connect_wlan():
            try:
                """通过网络校准时间"""
                ntptime.settime()  # 修改设备时间,到这就已经设置好了
                print("时间以校准")
                jiaozhun = 1
            except Exception as e:
                    jiaozhun = 0
        else:
            tft.text(16, t1, 0, 0, st.color565(0, 0, 0), st.color565(255, 255, 255))


# # 定义按键控制对象
# key1 = Pin(32, Pin.IN, Pin.PULL_UP)
# key2 = Pin(33, Pin.IN, Pin.PULL_UP)
# key1.irq(key1_irq, Pin.IRQ_FALLING)  # 配置key1外部中断，下降沿触发
# key2.irq(key2_irq, Pin.IRQ_FALLING)  # 配置key2外部中断，下降沿触发
# val = 3

async def AIZK():
    global Error, k1, k2, k3, k4, k5, k6, k7, k8, K_a, K_b
    print("艾掌控")
    while True:
        uart2.write(bytes([0xFF, 0x06, 0x01, 0x55, 0x5B]))
        await asyncio.sleep(1)
        data = uart2.read()
        if data != None and len(data) == 54:  # 同步开关状态
            K_a = int(((data.hex())[5:8]), 16)
            k1 = int(bin(int(((data.hex())[5:8]), 16))[-1:])
            k2 = int(bin(int(((data.hex())[5:8]), 16))[-2:-1])
            k3 = int(bin(int(((data.hex())[5:8]), 16))[-3:-2])
            k4 = int(bin(int(((data.hex())[5:8]), 16))[-4:-3])
            k5 = int(bin(int(((data.hex())[5:8]), 16))[-5:-4])
            k6 = int(bin(int(((data.hex())[5:8]), 16))[-6:-5])
            k7 = int(bin(int(((data.hex())[5:8]), 16))[-7:-6])
            k8 = int(bin(int(((data.hex())[5:8]), 16))[-8:-7])
            
            try:
                IM1253B()
        #             ac_TFT()
            except Exception as e:
                Error = "IM1253B Error",e
                print(Error)
                
            try:
                MPPT()
        #             mppt_TFT()
            except Exception as e:
                Error = "MPPT Error",e
                print(Error)
                

async def loop():
    global t1, t3, t4, t5, f5, Error
    # 开启定时器，定时发送心跳
    tim1 = Timer(1)
    tim1.init(period=100, mode=Timer.PERIODIC, callback=Bfyclient)
    
    tim2 = Timer(2)
    tim2.init(period=1000, mode=Timer.PERIODIC, callback=time_irq)
    
    await asyncio.gather(AC(), AIZK(),shijian())

def auto():
        print(time.time())
        print("启动TFT屏幕")
        tft7789()
        print(time.time())
        asyncio.run(loop())

        
        


